`include "mycpu.h"

module mycpu_top(
    input  wire        clk,
    input  wire        resetn,
    // inst sram interface
    output wire inst_sram_req,
    output wire inst_sram_wr,
    output wire [1:0] inst_sram_size,
    output wire [3:0] inst_sram_wstrb,
    output wire [31:0] inst_sram_addr,
    output wire [31:0] inst_sram_wdata,
    input wire inst_sram_addr_ok,
    input wire inst_sram_data_ok,
    input wire [31:0] inst_sram_rdata,
    // data sram interface
    output wire data_sram_req,
    output wire data_sram_wr,
    output wire [1:0] data_sram_size,
    output wire [31:0] data_sram_addr,
    output wire [3:0] data_sram_wstrb,
    output wire [31:0] data_sram_wdata,
    input wire data_sram_addr_ok,
    input wire data_sram_data_ok,
    input wire [31:0] data_sram_rdata,
    // trace debug interface
    output wire [31:0] debug_wb_pc,
    output wire [ 3:0] debug_wb_rf_we,
    output wire [ 4:0] debug_wb_rf_wnum,
    output wire [31:0] debug_wb_rf_wdata
);

reg         reset;
always @(posedge clk) reset <= ~resetn;

wire         ds_allowin;
wire         es_allowin;
wire         ms_allowin;
wire         ws_allowin;
wire         fs_to_ds_valid;
wire         ds_to_es_valid;
wire         es_to_ms_valid;
wire         ms_to_ws_valid;
wire         es_valid;
wire         ms_valid;
wire         ws_valid;
wire [`FS_TO_DS_WD -1:0] fs_to_ds_bus;
wire [`DS_TO_ES_WD -1:0] ds_to_es_bus;
wire [`ES_TO_MS_WD -1:0] es_to_ms_bus;
wire [`MS_TO_WS_WD -1:0] ms_to_ws_bus;
wire [`WS_TO_RF_WD -1:0] ws_to_rf_bus;
wire [`BR_BUS_WD -1:0] br_bus;
wire [31:0] ws_pc_gen_exec;
wire exec_flush;


if_stage u_if_stage(
    .clk (clk),
    .reset (reset),
    .ds_allowin (ds_allowin),
    .br_bus (br_bus),
    .fs_to_ds_valid (fs_to_ds_valid),
    .fs_to_ds_bus (fs_to_ds_bus),
    .exec_flush(exec_flush),
    .fs_ex_entry(ws_pc_gen_exec),
    .inst_sram_req(inst_sram_req),
    .inst_sram_wr(inst_sram_wr),
    .inst_sram_size(inst_sram_size),
    .inst_sram_wstrb(inst_sram_wstrb),
    .inst_sram_addr(inst_sram_addr),
    .inst_sram_wdata (inst_sram_wdata),
    .inst_sram_addr_ok(inst_sram_addr_ok),
    .inst_sram_data_ok(inst_sram_data_ok),
    .inst_sram_rdata (inst_sram_rdata)
);

id_stage u_id_stage(
    .clk (clk),
    .reset (reset),
    .es_allowin (es_allowin),
    .ds_allowin (ds_allowin),
    .fs_to_ds_valid (fs_to_ds_valid),
    .fs_to_ds_bus (fs_to_ds_bus),
    .ds_to_es_valid (ds_to_es_valid),
    .ds_to_es_bus (ds_to_es_bus),
    .br_bus (br_bus),
    .ws_to_rf_bus (ws_to_rf_bus),
    .out_ws_valid(ws_valid),
    .es_to_ms_bus(es_to_ms_bus),
    .out_es_valid(es_valid),
    .ms_to_ws_bus(ms_to_ws_bus),
    .out_ms_valid(ms_valid),
    .exec_flush(exec_flush)
);

exe_stage u_exe_stage(
    .clk (clk),
    .reset (reset),
    .ms_allowin (ms_allowin),
    .es_allowin (es_allowin),
    .ds_to_es_valid (ds_to_es_valid),
    .ds_to_es_bus (ds_to_es_bus),
    .es_to_ms_valid (es_to_ms_valid),
    .es_to_ms_bus (es_to_ms_bus),
    .data_sram_req(data_sram_req),
    .data_sram_wr(data_sram_wr),
    .data_sram_size(data_sram_size),
    .data_sram_addr (data_sram_addr),
    .data_sram_wstrb(data_sram_wstrb),
    .data_sram_wdata (data_sram_wdata),
    .data_sram_addr_ok(data_sram_addr_ok),
    .out_es_valid(es_valid),
    .exec_flush(exec_flush)
);

mem_stage u_mem_stage(
    .clk (clk),
    .reset (reset),
    .ws_allowin (ws_allowin),
    .ms_allowin (ms_allowin),
    .es_to_ms_valid (es_to_ms_valid),
    .es_to_ms_bus (es_to_ms_bus),
    .ms_to_ws_valid (ms_to_ws_valid),
    .ms_to_ws_bus (ms_to_ws_bus),
    .data_sram_data_ok(data_sram_data_ok),
    .data_sram_rdata (data_sram_rdata),
    .out_ms_valid(ms_valid),
    .exec_flush(exec_flush)
);

wb_stage u_WB_stage(
    .clk (clk),
    .reset (reset),
    .ws_allowin (ws_allowin),
    .ms_to_ws_valid (ms_to_ws_valid),
    .ms_to_ws_bus (ms_to_ws_bus),
    .ws_to_rf_bus (ws_to_rf_bus),
    .exec_flush(exec_flush),
    .ws_pc_gen_exec(ws_pc_gen_exec),
    .debug_wb_rf_pc (debug_wb_pc),
    .debug_wb_rf_we (debug_wb_rf_we),
    .debug_wb_rf_wnum (debug_wb_rf_wnum),
    .debug_wb_rf_wdata (debug_wb_rf_wdata),
    .out_ws_valid(ws_valid)
);

endmodule
